/**
 * 
 */
package com.dalonedrau.jogl.opengl.sprite;

import com.dalonedrau.jogl.engine.GlobalConsts;
import com.dalonedrau.jogl.opengl.ui.LineOfText;
import com.dalonedrau.pool.PooledStringBuilder;
import com.dalonedrau.pool.StringBuilderPool;
import com.dalonedrau.vectors.Vector3;

/**
 * @author Donald
 */
public final class GroupOfImages extends SpriteBaseImpl {
	/** list referencing which indices in the images array are in use. */
	private boolean[]			exists		= new boolean[0];
	/** storage array for rendering values. */
	private float[]				floatStore	= new float[GlobalConsts.INT_032];
	/** the font reference id. */
	private int					fontRefId;
	/** the full value of the Height. */
	private int					fullHeight;
	/** the full value of the texture's bottom coordinates. */
	private float				fullTcBottom;
	/** the full value of the texture's left coordinates. */
	private float				fullTcLeft;
	/** the full value of the texture's right coordinates. */
	private float				fullTcRight;
	/** the full value of the texture's top coordinates. */
	private float				fullTcTop;
	/** the full value of the Width. */
	private int					fullWidth;
	/** the full value of the {@link SpriteBase}'s Xl position. */
	private float				fullXl;
	/** the full value of the {@link SpriteBase}'s Xr position. */
	private float				fullXr;
	/** the full value of the {@link SpriteBase}'s Yb position. */
	private float				fullYb;
	/** the full value of the {@link SpriteBase}'s Yt position. */
	private float				fullYt;
	/** the reference id of the texture used. */
	private int					imageRefId	= -GlobalConsts.INT_999;
	/** the group of images. */
	private BasicSpriteObject[]	images		= new BasicSpriteObject[0];
	/**
	 * the value of all modifications applied to the texture's bottom
	 * coordinates.
	 */
	private float				modTcBottom;
	/**
	 * the value of all modifications applied to the texture's left coordinates.
	 */
	private float				modTcLeft;
	/**
	 * the value of all modifications applied to the texture's right
	 * coordinates.
	 */
	private float				modTcRight;
	/**
	 * the value of all modifications applied to the texture's top coordinates.
	 */
	private float				modTcTop;
	/**
	 * the value of all modifications applied to the {@link SpriteBase}'s Xl
	 * position.
	 */
	private float				modXl;
	/**
	 * the value of all modifications applied to the {@link SpriteBase}'s Xr
	 * position.
	 */
	private float				modXr;
	/**
	 * the value of all modifications applied to the {@link SpriteBase}'s Yb
	 * position.
	 */
	private float				modYb;
	/**
	 * the value of all modifications applied to the {@link SpriteBase}'s Yt
	 * position.
	 */
	private float				modYt;
	/** the number of images in the group. */
	private int					numImages;
	/** the position. */
	private Vector3				position;
	/** the value of the texture's bottom coordinates. */
	private float				tcBottom;
	/** the value of the texture's left coordinates. */
	private float				tcLeft;
	/** the value of the texture's right coordinates. */
	private float				tcRight;
	/** the value of the texture's top coordinates. */
	private float				tcTop;
	/**
	 * Adds an image.
	 * @param image the {@link BasicSpriteObject} image
	 * @throws Exception if an error occurs
	 */
	public void addImage(final BasicSpriteObject image) throws Exception {
		if (imageRefId == -GlobalConsts.INT_999) {
			imageRefId = image.getImageRefId();
		} else {
			int tidOld = SpriteImageObjectFactory.getInstance().getImageById(
					imageRefId).getTextureId();
			int tidNew = SpriteImageObjectFactory.getInstance().getImageById(
					image.getImageRefId()).getTextureId();
			if (tidOld != tidNew) {
				PooledStringBuilder sb =
						StringBuilderPool.getInstance().getStringBuilder();
				sb.append("Unable to add sprite image to GroupOfImages. ");
				sb.append("New texture id does not match previous id.");
				Exception ex = new Exception(sb.toString());
				sb.returnToPool();
				throw ex;
			}
		}
		int index = getIndexOfNextEmptyImage();
		images[index] = image;
		exists[index] = true;
		numImages++;
		if (floatStore.length < numImages * GlobalConsts.INT_032) {
			floatStore = new float[numImages * GlobalConsts.INT_032];
		}
		super.setFloatStoreNumber(0);
	}
	/** Clears all lines. */
	public void clearImages() {
		for (int i = 0; i < images.length; i++) {
			images[i] = null;
			exists[i] = false;
		}
		numImages = 0;
		super.setFloatStoreNumber(0);
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float[] getFloatStore() {
		return floatStore;
	}
	/**
	 * Gets the font reference id.
	 * @return {@link int}
	 */
	public int getFontRefId() {
		return fontRefId;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public int getFullHeight() {
		return fullHeight;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getFullTCBottom() {
		return fullTcBottom;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getFullTCLeft() {
		return fullTcLeft;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getFullTCRight() {
		return fullTcRight;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getFullTCTop() {
		return fullTcTop;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public int getFullWidth() {
		return fullWidth;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getFullX1() {
		// TODO Auto-generated method stub
		return 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getFullX2() {
		// TODO Auto-generated method stub
		return 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getFullX3() {
		// TODO Auto-generated method stub
		return 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getFullXl() {
		return fullXl;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getFullXr() {
		return fullXr;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getFullY1() {
		// TODO Auto-generated method stub
		return 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getFullY2() {
		// TODO Auto-generated method stub
		return 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getFullY3() {
		// TODO Auto-generated method stub
		return 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getFullYb() {
		return fullYb;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getFullYt() {
		return fullYt;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public int getHeight() {
		// TODO Auto-generated method stub
		return 0;
	}
	/**
	 * Gets a specific image by its index.
	 * @param index the index
	 * @return {@link BasicSpriteObject}
	 * @throws Exception if an error occurs
	 */
	public BasicSpriteObject getImage(final int index) throws Exception {
		return images[index];
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public int getImageRefId() {
		return imageRefId;
	}
	/**
	 * Gets the array index of the next empty {@link LineOfText} instance.
	 * @return int
	 */
	public int getIndexOfNextEmptyImage() {
		int index = -1;
		// look for a line that doesn't exist
		for (int i = 0; i < images.length; i++) {
			if (!exists[i]) {
				index = i;
				break;
			}
		}
		if (index == -1) {
			index = images.length;
			// extend the arrays
			// start with the images array
			BasicSpriteObject[] dest = new BasicSpriteObject[images.length + 1];
			System.arraycopy(images, 0, dest, 0, images.length);
			// extend the exists array
			boolean[] destb = new boolean[images.length + 1];
			System.arraycopy(exists, 0, destb, 0, images.length);
			destb[images.length] = false;
			images = dest;
			exists = destb;
			dest = null;
			destb = null;
		}
		return index;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public int getModHeight() {
		// TODO Auto-generated method stub
		return 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getModTCBottom() {
		return modTcBottom;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getModTCLeft() {
		return modTcLeft;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getModTCRight() {
		return modTcRight;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getModTCTop() {
		return modTcTop;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public int getModWidth() {
		// TODO Auto-generated method stub
		return 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getModXl() {
		return modXl;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getModXr() {
		return modXr;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getModYb() {
		return modYb;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getModYt() {
		return modYt;
	}
	/**
	 * Gets the number of images in the group.
	 * @return <code>int</code>
	 */
	public int getNumberOfImages() {
		return numImages;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final Vector3 getPosition() {
		return position;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getTCBottom() {
		return tcBottom;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getTCLeft() {
		return tcLeft;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getTCRight() {
		return tcRight;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getTCTop() {
		return tcTop;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public int getType() {
		return SpriteBase.TYPE_01_GROUP_IMAGE;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public int getWidth() {
		// TODO Auto-generated method stub
		return 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getX1() {
		// TODO Auto-generated method stub
		return 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getX2() {
		// TODO Auto-generated method stub
		return 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getX3() {
		// TODO Auto-generated method stub
		return 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getY1() {
		// TODO Auto-generated method stub
		return 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getY2() {
		// TODO Auto-generated method stub
		return 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float getY3() {
		// TODO Auto-generated method stub
		return 0;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setFullHeight(final int h) {
		fullHeight = h;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setFullTCBottom(float val) {
		fullTcBottom = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setFullTCLeft(float val) {
		fullTcLeft = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setFullTCRight(float val) {
		fullTcRight = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setFullTCTop(float val) {
		fullTcTop = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setFullWidth(final int w) {
		fullWidth = w;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setFullX1(float val) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setFullX2(float val) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setFullX3(float val) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setFullXl(final float val) {
		fullXl = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setFullXr(final float val) {
		fullXr = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setFullY1(float val) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setFullY2(float val) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setFullY3(float val) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setFullYb(final float val) {
		fullYb = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setFullYt(final float val) {
		fullYt = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setHeight(int h) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setImageRefId(int refId) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setModHeight(int h) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setModTCBottom(float val) {
		modTcBottom = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setModTCLeft(float val) {
		modTcLeft = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setModTCRight(float val) {
		modTcRight = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setModTCTop(float val) {
		modTcTop = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setModWidth(int w) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setModXl(final float val) {
		modXl = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setModXr(final float val) {
		modXr = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setModYb(final float val) {
		modYb = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setModYt(final float val) {
		modYt = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setPosition(final double x, final double y, final double z) {
		if (position != null) {
			position.set(x, y, z);
		} else {
			position = new Vector3(x, y, z);
		}
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public final void setPosition(final Vector3 v) {
		position = v;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setTCBottom(float val) {
		tcBottom = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setTCLeft(float val) {
		tcLeft = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setTCRight(float val) {
		tcRight = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setTCTop(float val) {
		tcTop = val;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setWidth(int w) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setX1(float val) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setX2(float val) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setX3(float val) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setY1(float val) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setY2(float val) {
		// TODO Auto-generated method stub

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setY3(float val) {
		// TODO Auto-generated method stub

	}
}
